import pyaudio
import wave
import logging
import os

def record_audio(log,filename, record_seconds=4, sample_rate=16000, channels=1, chunk=2048):
    """
    录制音频并保存为文件。

    参数:
        filename (str): 保存录音的文件名。
        record_seconds (int): 录音时长（秒），默认为 5 秒。
        sample_rate (int): 采样率，默认为 16000 Hz。
        channels (int): 声道数，默认为 1（单声道）。
        chunk (int): 每次读取的帧数，默认为 2048。

    返回:
        bool: 录音成功返回 True，否则返回 False。
    """
    
    # 参数校验
    if record_seconds <= 0:
        log.error("录音时长必须大于 0")
        return False
    if sample_rate <= 0:
        log.error("采样率必须大于 0")
        return False
    if channels not in [1, 2]:
        log.error("声道数必须为 1（单声道）或 2（立体声）")
        return False
    if chunk <= 0:
        log.error("帧数必须大于 0")
        return False

    audio = None
    stream = None
    
    # 文件不存在则创建
    if not os.path.exists(os.path.dirname(filename)):
        os.makedirs(os.path.dirname(filename))

    try:
        # 初始化 pyaudio
        audio = pyaudio.PyAudio()
        # 打开音频流
        stream = audio.open(format=pyaudio.paInt16,
                            channels=channels,
                            rate=sample_rate,
                            input=True,
                            frames_per_buffer=chunk)
        # 录音
        frames = []
        log.info(f"开始录音，时长: {record_seconds} 秒")

        for _ in range(0, int(sample_rate / chunk * record_seconds)):
            data = stream.read(chunk)
            frames.append(data)

        log.info("录音结束")

        # 保存录音文件
        with wave.open(filename, 'wb') as wf:
            wf.setnchannels(channels)
            wf.setsampwidth(audio.get_sample_size(pyaudio.paInt16))
            wf.setframerate(sample_rate)
            wf.writeframes(b''.join(frames))

        return True

    except Exception as e:
        log.error(f"录音失败: {e}")
        return False

    finally:
        # 确保资源释放
        if stream:
            stream.stop_stream()
            stream.close()
            log.info("音频流已关闭")
        if audio:
            audio.terminate()